package com.neusoft.bizcore.activiti.repository.impl;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import com.neusoft.bizcore.activiti.enums.WorkOrderStatus;
import com.neusoft.bizcore.activiti.model.QWorkOrder;
import com.neusoft.bizcore.activiti.model.WorkOrder;
import com.neusoft.bizcore.activiti.repository.CustomizedWorkOrderRepository;
import com.neusoft.bizcore.web.jpa.repository.AbstractRepository;
import com.neusoft.bizcore.web.support.Searchable;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;

public class CustomizedWorkOrderRepositoryImpl extends AbstractRepository implements CustomizedWorkOrderRepository {

    @Override
    public Page<WorkOrder> search(final Pageable pageable, final Searchable searchable) {
        final QWorkOrder qWorkOrder = QWorkOrder.workOrder;
        final BooleanBuilder where = this.buildWhere(searchable);
        final JPAQuery<WorkOrder> query = this.query().selectFrom(qWorkOrder);
        query.where(where);
        return super.search(query, pageable);
    }

    @Override
    public long count(final Searchable searchable) {
        final QWorkOrder qWorkOrder = QWorkOrder.workOrder;
        final BooleanBuilder where = this.buildWhere(searchable);
        final JPAQuery<WorkOrder> query = this.query().selectFrom(qWorkOrder);
        query.where(where);
        return query.fetchCount();
    }

    @Override
    protected Class<?> getModelClass() {
        return WorkOrder.class;
    }

    private BooleanBuilder buildWhere(final Searchable searchable) {
        final BooleanBuilder where = new BooleanBuilder();
        final QWorkOrder qWorkOrder = QWorkOrder.workOrder;

        // 工单类型
        where.and(super.equalsStr(qWorkOrder.type, searchable, "type"));
        // 工单标题
        where.and(super.containsStr(qWorkOrder.title, searchable, "title"));
        // 时间
        where.and(super.beforeOrEqualsDate(qWorkOrder.createTime, searchable, "beforeOrEqualData"));
        where.and(super.afterOrEqualsDate(qWorkOrder.createTime, searchable, "afterOrEqualData"));
        // 人员
        where.and(super.equalsStr(qWorkOrder.applyUserId, searchable, "userName"));

        // 工单实例集合
        where.and(super.inStrings(qWorkOrder.instanceId, searchable, "instanceIds"));

        // 工单状态
        where.and(super.equalsEnum(qWorkOrder.status, searchable, "status", value -> WorkOrderStatus.valueOf(value)));

        // 查询多个状态
        final String[] statusArray = searchable.getStrArray("statusArray");
        if ((statusArray != null) && (statusArray.length != 0)) {
            final List<WorkOrderStatus> list = Stream.of(statusArray).collect(Collectors.toList()).stream()
                    .map(value -> WorkOrderStatus.valueOf(value)).collect(Collectors.toList());
            where.and(qWorkOrder.status.in(list));
        }

        // 更新时间
        where.and(super.beforeOrEqualsDate(qWorkOrder.updateTime, searchable, "beforeUpdateAt"));
        where.and(super.afterOrEqualsDate(qWorkOrder.updateTime, searchable, "afterUpdateAt"));

        // 模糊查询
        if (!StringUtils.isEmpty(searchable.getStrValue("globalSearch"))) {
            final BooleanBuilder whereGlobal = new BooleanBuilder();
            whereGlobal.or(super.containsStr(qWorkOrder.title, searchable, "globalSearch"));
            whereGlobal.or(super.containsStr(qWorkOrder.workOrderNum, searchable, "globalSearch"));
            where.and(whereGlobal);
        }
        return where;
    }
}
